#!/usr/bin/env python
# coding=UTF-8
import random
import logging
import json
import time
import datetime
import copy

import config
import dao

from nsq.http import nsqd
import redisco
from redisco.containers import List, Hash
from audioop import reverse

def get_match_base_score(bid, mid, all_round, game_round, rid):
    db = dao.Game_DB()
    room_info = db.get_room(rid, bid)
    win_score = room_info['base_score'] + all_round - game_round + 1
    return win_score

def json_encode(data):
    return json.dumps(data, separators=(',', ':'))

def nsq_pub(message, topic='response'):
    try:
        nsq_client = nsqd.Client("http://%s/" % config.NSQ_HTTP)
        if isinstance(message, dict):
            message = json_encode(message)
        logging.info(u"推送消息:%s" % message)
        nsq_client.pub(topic, message)
        return True
    except:
        logging.error("nsq send error", exc_info=True)
        return False

def get_last_data(reader, bid, uid, data):
    uid = str(uid)
    user_info = Hash("%s_%s" % (bid, uid))
    rid = user_info['rid']
    if not rid:
        rid = data.get("rid", "")
    room = Hash("r:%s" % rid)
    tdh = DouDiZhu(rid, bid)
    last_put_user = tdh.room['last_put_user']
    last_put_card = tdh.room['last_put_card']
    if not last_put_card:
        last_put_card = []
    else:
        last_put_card = last_put_card.split(",")
    all_player_data = []
    l = List("r:%s:p" % rid)
    members = l.members
    for member in members:
        if member:
            p = Player(member, bid, rid)
            player_data = p.get_data()
            player_data['status'] = 1
            if member == uid:
                player_data['current_card'] = sorted(player_data['current_card'], key=lambda x:int(x), reverse=True)
            player_data['left_num'] = len(player_data['current_card'])
            all_player_data.append(player_data)
        
    dealer = tdh.room['dealer']
    if not dealer:
        dealer = ''
    bottom_card = tdh.bottom_card.members
    data = {"act":"get_last_data", 
            "last_put_user":last_put_user, 
            "last_put_card":last_put_card, 
            "bottom_card":bottom_card,
            "game_round":room['game_round'],
            "all_round":room['all_round'],
            "dealer":dealer,
            "all_player_data":all_player_data,
            "rid":rid,
            "status":room['status'],
           }
    
    nsq_pub({"b":bid, "u":uid, "t":"game", "d":data})
    stop_pop_user = tdh.room['stop_pop_user']
    stop_pop_act = tdh.room['stop_pop_act']
    if stop_pop_user:
        if stop_pop_act == 'turn_rob':
            tdh.notify_turn_rob(stop_pop_user)
            return
        if stop_pop_user == uid:
            my_seat = members.index(uid)
            pre_user = members[my_seat-1]
            tdh.notify_next_user(pre_user)
        else:
            if not last_put_user:
                put_type = "free"
            else:
                put_type = "follow"
            nsq_pub({"b":bid, "u":uid, "t":"game", "d":{"act":"turn_put", "put_type":put_type, "uid":stop_pop_user, "rid":rid, "valid_list":[], "tips_list":[], "last_put_card":last_put_card, "last_put_type":"", "last_put_point":""}})
        
        
class Player():
    def __init__(self, uid, bid='', rid='', first=False):
        self.uid = uid
        self.bid = bid
        self.rid = rid
        if first:
            redisco.connection.delete("p:%s:%s:%s:current_card" % (bid, uid, rid))
            redisco.connection.delete("p:%s:%s:%s:out_card" % (bid, uid, rid))
            #redisco.connection.delete("p:%s:%s:%s:bomb" % (bid, uid, rid))
            #redisco.connection.delete("p:%s:%s:%s:put_num" % (bid, uid, rid))
            redisco.connection.delete("p:%s:%s:%s" % (bid, uid, rid))
            self.score = Hash("p:%s:%s:%s" % (bid, uid, rid))
            self.score['score'] = 0
            self.score['win_score'] = 0
            self.score['put_num'] = 0
            self.score['bomb'] = 0
        else:
            self.score = Hash("p:%s:%s:%s" % (bid, uid, rid))
        self.current_card = List("p:%s:%s:%s:current_card" % (bid, uid, rid))
        self.out_card = List("p:%s:%s:%s:out_card" % (bid, uid, rid))
        #self.bomb = List("p:%s:%s:%s:bomb" % (bid, uid, rid))
        #self.put_num = List("p:%s:%s:%s:put_num" % (bid, uid, rid))
    
    def clear(self):
        redisco.connection.delete("p:%s:%s:%s:current_card" % (self.bid, self.uid, self.rid))
        redisco.connection.delete("p:%s:%s:%s:out_card" % (self.bid, self.uid, self.rid))
        redisco.connection.delete("p:%s:%s:%s" % (self.bid, self.uid, self.rid))
        
    def get_data(self):
        return {"uid":self.uid,
                "current_card":self.current_card.members,
                "bomb":self.score['bomb'],
                "score":self.score['score'],
                }

class DouDiZhu():
    def __init__(self, rid, bid, dealer=None):
        self.rid = str(rid)
        self.bid = bid
        if dealer:
            redisco.connection.delete("r:%s:current_card" % rid)
            redisco.connection.delete("r:%s:bottom_card" % rid)
            redisco.connection.delete("r:%s:mid" % rid)
            self.room = Hash("r:%s" % rid)
            self.room['dealer'] = dealer
            self.room['last_get_user'] = dealer
            self.room['last_put_user'] = ''
            self.room['stop_pop_user'] = ''
            self.room['stop_pop_act'] = ''
            self.room['bomb'] = 0
        else:
            self.room = Hash("r:%s" % rid)
        self.current_card = List("r:%s:current_card" % rid)
        self.bottom_card = List("r:%s:bottom_card" % rid)
        l = List("r:%s:p" % rid)
        self.members = l.members
    
    def incr_mid(self):
        return redisco.connection.incr("r:%s:mid" % self.rid)
    
    def get_card_point(self, c):
        '''获取某张扑克牌的点数'''
        return int(c)/10
    
    def trans_card(self, card):
        '''转换手牌列表,去掉花色'''
        res = []
        card.sort()
        for c in card:
            card_point = self.get_card_point(c)
            res.append(card_point)
        return res
    
    def is_pair(self, card_list):
        '''是否对子'''
        if len(card_list) == 2:
            if card_list[0] == card_list[1]:
                return True, [card_list[0]]
        return False, []
    
    def is_seq_pair(self, card_list):
        '''连对'''
        res = []
        card_list.sort()
        if len(card_list) >= 6 and len(card_list) % 2 == 0:
            for c in set(card_list):
                if card_list.count(c) != 2:
                    return False, []
                res.append(c)
            res.sort()
            start_i = res[0]
            end_i = res[-1]
            if res == range(start_i, end_i+1) and end_i < 13:
                return True, [start_i, end_i]
        return False, []
    
    def is_rocket(self, card_list):
        '''王炸'''
        if len(card_list) == 2:
            if 14 in card_list and 15 in card_list:
                return True, [card_list[0]]
        return False, []
    
    def is_bomb(self, card_list):
        '''炸弹'''
        if len(card_list) == 4:
            if card_list[0] == card_list[1] and card_list[0] == card_list[2] and card_list[0] == card_list[3]:
                return True, [card_list[0]]
        return False, []
    
    def is_bomb_one(self, card_list):
        '''炸弹带1'''
        bomb_list = []
        single_list = []
        if len(card_list) == 5:
            for c in set(card_list):
                c_cnt = card_list.count(c)
                if c_cnt == 4:
                    bomb_list.append(c)
                else:
                    single_list.extend([c]*c_cnt)
            if len(bomb_list) == 1 and len(single_list) == 1:
                return True, bomb_list
        return False, []
    
    def is_bomb_two(self, card_list):
        '''炸弹带2'''
        bomb_list = []
        single_list = []
        if len(card_list) == 6:
            for c in set(card_list):
                c_cnt = card_list.count(c)
                if c_cnt == 4:
                    bomb_list.append(c)
                else:
                    single_list.extend([c]*c_cnt)
            if len(bomb_list) == 1 and len(single_list) == 2:
                return True, bomb_list
        return False, []
    
    def is_triple_without(self, card_list):
        '''三不带'''
        if len(card_list) == 3:
            if card_list[0] == card_list[1] and card_list[0] == card_list[2]:
                return True, [card_list[0]]
        return False, []
    
    def is_triple_one(self, card_list):
        '''三带一'''
        triple_list = []
        single_list = []
        if len(card_list) == 4:
            for c in set(card_list):
                c_cnt = card_list.count(c)
                if c_cnt == 3:
                    triple_list.append(c)
                else:
                    single_list.extend([c]*c_cnt)
            if len(triple_list) == 1 and len(single_list) == 1:
                return True, triple_list
        return False, []
    
    def is_triple_two(self, card_list):
        '''三带二'''
        triple_list = []
        pair_list = []
        if len(card_list) == 5:
            for c in set(card_list):
                c_cnt = card_list.count(c)
                if c_cnt == 3:
                    triple_list.append(c)
                elif c_cnt == 2:
                    pair_list.append(c)
                else:
                    return  False, []
            if len(triple_list) == 1 and len(pair_list) == 1:
                return True, triple_list
        return False, []
    
    def is_seq(self, card_list):
        '''顺子'''
        if len(card_list) >= 5:
            card_list.sort()
            start_i = card_list[0]
            end_i = card_list[-1]
            if card_list == range(start_i, end_i+1) and end_i < 13:
                return True, [start_i, end_i]
        return False, []
    
    def is_seq_triple_single(self, card_list):
        '''飞机带单'''
        single_list = []
        triple_list = []
        card_list.sort()
        if len(card_list) >= 8 and len(card_list) % 4 == 0:
            if 14 in card_list and 15 in card_list:
                return False, []
            for c in set(card_list):
                c_cnt = card_list.count(c)
                if c_cnt == 3 and c < 13:
                    triple_list.append(c)
                else:
                    single_list.extend([c]*c_cnt)
            if len(triple_list) >= 2:
                triple_list.sort()
                start_i = triple_list[0]
                end_i = triple_list[-1]
                if triple_list == range(start_i, end_i+1) and (len(card_list)- len(triple_list) * 3) == len(triple_list):
                    return True, [start_i, end_i]
                else:
                    seq_list = []
                    for i in range(1, len(triple_list)):
                        for j in range(len(triple_list)):
                            tmp_seq = range(triple_list[j], triple_list[j]+i)
                            if all(map(lambda x: x in triple_list, tmp_seq)):
                                seq_list.append(tmp_seq)
                    res = []
                    for seq in seq_list:
                        if len(seq) > len(res):
                            res = seq
                    if res and (len(card_list)-len(res)*3) == len(res):
                        return True, [res[0], res[-1]]
        return False, []
    
    def is_seq_triple_pair(self, card_list):
        '''飞机带对'''
        pair_list = []
        triple_list = []
        card_list.sort()
        if len(card_list) >= 10 and len(card_list) % 5 == 0:
            if 14 in card_list and 15 in card_list:
                return False, []
            for c in set(card_list):
                c_cnt = card_list.count(c)
                if c_cnt == 3 and c < 13:
                    triple_list.append(c)
                elif c_cnt == 2:
                    pair_list.append(c)
                else:
                    return False, []
            if len(triple_list) >= 2:
                triple_list.sort()
                start_i = triple_list[0]
                end_i = triple_list[-1]
                if triple_list == range(start_i, end_i+1) and (len(card_list)- len(triple_list) * 3) == len(triple_list) * 2:
                    return True, [start_i, end_i]
                else:
                    seq_list = []
                    for i in range(1, len(triple_list)):
                        for j in range(len(triple_list)):
                            tmp_seq = range(triple_list[j], triple_list[j]+i)
                            if all(map(lambda x: x in triple_list, tmp_seq)):
                                seq_list.append(tmp_seq)
                    res = []
                    for seq in seq_list:
                        if len(seq) > len(res):
                            res = seq
                    if res and (len(card_list)-len(res)*3) == len(res)*2:
                        return True, [res[0], res[-1]]
        return False, []
    
    def is_seq_triple(self, card_list):
        '''飞机不带'''
        triple_list = []
        card_list.sort()
        if len(card_list) >= 6 and len(card_list) % 3 == 0:
            for c in set(card_list):
                c_cnt = card_list.count(c)
                if c_cnt == 3 and c < 13:
                    triple_list.append(c)
                else:
                    return False, []
            if len(triple_list) >= 2:
                triple_list.sort()
                start_i = triple_list[0]
                end_i = triple_list[-1]
                if triple_list == range(start_i, end_i+1) and len(card_list) == len(triple_list) * 3:
                    return True, [start_i, end_i]
        return False, []
    
    def get_win_type(self, dealer, dealer_win):
        if dealer_win:
            put_num = 0
            for member in self.members:
                if member != dealer:
                    member_player = Player(member, self.bid, self.rid)
                    put_num += int(member_player.score['put_num'])
            if put_num == 0:
                return 'chuntian'
        else:
            dealer_put_num = 0
            member_put = []
            for member in self.members:
                member_player = Player(member, self.bid, self.rid)
                if member != dealer:
                    member_put.append(int(member_player.score['put_num']))
                else:
                    dealer_put_num = int(member_player.score['put_num'])
            if dealer_put_num == 1 and 0 in member_put:
                return 'fanchun'
        return ''
        
    def get_card_type(self, card):
        card_list = self.trans_card(card)
        card_len = len(card_list)
        if card_len >= 6:
            #检查是否顺子
            #检查是否三带二
            #检查是否连对
            #检查是否飞机
            #四带2
            res = self.is_seq(card_list)
            if res[0]:
                return 'seq', res[1]
            if card_len % 2 == 0:
                res = self.is_seq_pair(card_list)
                if res[0]:
                    return 'seq_pair', res[1]
            if card_len % 3 == 0:
                res = self.is_seq_triple(card_list)
                if res[0]:
                    return 'seq_triple', res[1]
            if card_len % 4 == 0:
                res = self.is_seq_triple_single(card_list)
                if res[0]:
                    return 'seq_triple_single', res[1]
            if card_len % 5 == 0:
                res = self.is_seq_triple_pair(card_list)
                if res[0]:
                    return 'seq_triple_pair', res[1]
            if card_len == 6:
                res = self.is_bomb_two(card_list)
                if res[0]:
                    return 'bomb_two', res[1]
        elif card_len == 5:
            #3带2，4带1，顺子
            res = self.is_seq(card_list)
            if res[0]:
                return 'seq', res[1]
            res = self.is_triple_two(card_list)
            if res[0]:
                return 'triple_two', res[1]
            #res = self.is_bomb_one(card_list)
            #if res[0]:
            #    return 'bomb_one', res[1]
        elif card_len == 4:
            #检查连对
            #检查炸弹
            #检查三带一
            res = self.is_bomb(card_list)
            if res[0]:
                return 'bomb', res[1]
            res = self.is_triple_one(card_list)
            if res[0]:
                return 'triple_one', res[1]
        elif card_len == 3:
            #三不带
            res = self.is_triple_without(card_list)
            if res[0]:
                return 'triple', res[1]
        elif card_len == 2:
            #对子
            #火箭
            res = self.is_rocket(card_list)
            if res[0]:
                return 'rocket', res[1]
            res = self.is_pair(card_list)
            if res[0]:
                return 'pair', res[1]
        elif card_len == 1:
            return 'single', card_list
        return '', []
    
    def compare_card(self, card1, card2):
        #判断card2是否比card1牌型大
        card_type2 = self.get_card_type(card2)
        card_type1 = self.get_card_type(card1)
        if card_type1[0] == card_type2[0]:
            #相同类型的牌
            if len(card1) != len(card2):
                return False
            card1_point_s = card_type1[1][0]
            card1_point_e = card_type1[1][-1]
            card2_point_s = card_type2[1][0]
            card2_point_e = card_type2[1][-1]
            if card2_point_s > card1_point_s and card2_point_e > card1_point_e:
                return True
        elif card_type2[0] == 'rocket':
            return True
        elif card_type1[0] != 'rocket' and card_type2[0] == 'bomb':
            return True
        return False
    
    def get_card_by_point(self, card, card_point, num=4):
        '''取手牌中某个点数的固定数量的牌'''
        res = []
        for c in card:
            if self.get_card_point(c) == card_point and len(res) < num:
                res.append(c)
        return res
    
    def get_bomb_card(self, card, bomb_point=0):
        '''取手牌中大于bomb_point的炸弹, 为0则返回所有炸弹'''
        res = []
        tips_list = []
        card_list = self.trans_card(card)
        bomb_list = []
        for c in set(card_list):
            if card_list.count(c) == 4 and c > bomb_point:
                bomb_list.append(c)
        for bomb in bomb_list:
            tips_card = []
            for i in range(1, 5):
                tips_card.append(str(bomb * 10 + i))
            res.extend(tips_card)
            tips_list.append(tips_card)
        if 14 in card_list and 15 in card_list:
            rocket = ['141', '151']
            res.extend(rocket)
            tips_list.append(rocket)
        return res, tips_list
    
    def get_single_card(self, card, single_point=0):
        '''取手牌中大于single_point点数的单张牌'''
        res = []
        tips_list = []
        card_list = self.trans_card(card)
        for c in set(card_list):
            if c > single_point:
                rs = self.get_card_by_point(card, c)
                res.extend(rs)
                tips_card = rs[:1]
                tips_list.append(tips_card)
        return res, tips_list
    
    def get_pair_card(self, card, pair_point=0):
        '''取手牌中大于pair_point点数的对子扑克牌'''
        res = []
        tips_list = []
        pair_list = []
        card_list = self.trans_card(card)
        for c in set(card_list):
            if card_list.count(c) >= 2:
                if c > pair_point:
                    pair_list.append(c)
        for card_point in pair_list:
            rs = self.get_card_by_point(card, card_point)
            res.extend(rs)
            tips_card = rs[:2]
            tips_list.append(tips_card)
        return res, tips_list
    
    def get_seq_card(self, card, seq_s=0, num=5):
        '''获取手牌中包含大于某个点数的顺子对应的扑克牌'''
        seq_list = []
        end_c = 13 - num
        for start_c in range(seq_s+1, end_c+1):
            rs = range(start_c, start_c+num)
            seq_list.append(rs)
        card_list = self.trans_card(card)
        res = []
        tips_list = []
        has_seq_set = set()
        for seq in seq_list:
            if set(seq).issubset(set(card_list)):
                has_seq_set |= set(seq)
                tips_card = []
                for c in seq:
                    rs = self.get_card_by_point(card, c, 1)
                    tips_card.append(rs[0])
                tips_list.append(tips_card)
        has_seq_list = list(has_seq_set)
        for card_point in has_seq_list:
            rs = self.get_card_by_point(card, card_point)
            res.extend(rs)
        return res, tips_list
    
    def get_seq_pair_card(self, card, seq_s=0, num=3):
        '''取手牌中包含大于seq_s的连对'''
        seq_pair_list = []
        end_c = 13 - num
        for start_c in range(seq_s+1, end_c+1):
            rs = range(start_c, start_c+num)
            seq_pair_list.append(rs)
        card_list = self.trans_card(card)
        pair_list = []
        for c in set(card_list):
            if card_list.count(c) >= 2:
                pair_list.append(c)
        res = []
        tips_list = []
        has_seq_set = set()
        for seq in seq_pair_list:
            if set(seq).issubset(set(pair_list)):
                has_seq_set |= set(seq)
                tips_card = []
                for c in seq:
                    rs = self.get_card_by_point(card, c, 2)
                    tips_card.extend(rs)
                tips_list.append(tips_card)
        has_seq_list = list(has_seq_set)
        for card_point in has_seq_list:
            rs = self.get_card_by_point(card, card_point)
            res.extend(rs)
        return res, tips_list
    
    def get_triple_card(self, card, triple_point=0):
        '''取手牌中包含大于triple_point的3不带'''
        if len(card) < 3:
            return [], []
        res = []
        tips_list = []
        triple_list = []
        card_list = self.trans_card(card)
        for c in set(card_list):
            if card_list.count(c) >= 3:
                if c > triple_point:
                    triple_list.append(c)
        for card_point in triple_list:
            rs = self.get_card_by_point(card, card_point)
            res.extend(rs)
            tips_card = rs[:3]
            tips_list.append(tips_card)
        return res, tips_list
    
    def get_triple_one(self, card, triple_point=0):
        '''取手牌中包含大于triple_point的3带1'''
        if len(card) < 4:
            return [], []
        res = []
        tips_list = []
        triple_list = []
        card_list = self.trans_card(card)
        for c in set(card_list):
            if card_list.count(c) >= 3:
                if c > triple_point:
                    triple_list.append(c)
        
        for card_point in triple_list:
            rs = self.get_card_by_point(card, card_point)
            res.extend(rs)
            tips_card = rs[:3]
            with_card_list = []
            other_list = list(set(card_list) - set([card_point]))
            for c in other_list:
                rs = self.get_card_by_point(card, c, 3)
                with_card_list.extend(rs)
            with_card = with_card_list[:1]
            tips_card.extend(with_card)
            tips_list.append(tips_card)
        if res:
            return card, tips_list
        return res, tips_list
    
    def get_triple_two(self, card, triple_point=0):
        '''取手牌中包含大于triple_point的3带对子'''
        if len(card) < 5:
            return [], []
        res = []
        tips_list = []
        triple_list = []
        pair_list = []
        card_list = self.trans_card(card)
        for c in set(card_list):
            c_cnt = card_list.count(c)
            if c_cnt >= 3:
                if c > triple_point:
                    triple_list.append(c)
                if len(triple_list)>1 or c < triple_point:
                    pair_list.append(c)
            elif c_cnt == 2:
                pair_list.append(c)
        if not (pair_list and triple_list):
            return [], []
        for card_point in triple_list:
            rs = self.get_card_by_point(card, card_point)
            res.extend(rs)
            tips_card = rs[:3]
            with_card_list = []
            for c in pair_list:
                rs = self.get_card_by_point(card, c, 2)
                with_card_list.extend(rs)
                res.extend(rs)
            with_card = with_card_list[:2]
            tips_card.extend(with_card)
            tips_list.append(tips_card)
        return res, tips_list
    
    def get_bomb_two_card(self, card, bomb_point=0):
        '''取手牌中包含大于bomb'''
        if len(card) < 6:
            return [], []
        res = []
        tips_list = []
        bomb_list = []
        card_list = self.trans_card(card)
        for c in set(card_list):
            if card_list.count(c) >= 4:
                if c > bomb_point:
                    bomb_list.append(c)
        for card_point in bomb_list:
            rs = self.get_card_by_point(card, card_point)
            res.extend(rs)
            tips_card = rs[:4]
            with_card_list = []
            other_list = list(set(card_list) - set([card_point]))
            for c in other_list:
                rs = self.get_card_by_point(card, c, 2)
                with_card_list.extend(rs)
                    
            with_card = with_card_list[:2]
            if '141' in with_card and '151' in with_card:
                if len(with_card_list) >=3:
                    with_card = with_card_list[1:3]
                else:
                    continue
            tips_card.extend(with_card)
            tips_list.append(tips_card)
        if res:
            return card, tips_list
        return res, tips_list
    
    def get_seq_triple_card(self, card, seq_s=0, num=2):
        '''取手牌中包含大于seq_s的飞机'''
        if len(card) < 3 * num:
            return [], []
        seq_triple_list = []
        end_c = 13 - num
        for start_c in range(seq_s+1, end_c+1):
            rs = range(start_c, start_c+num)
            seq_triple_list.append(rs)
        card_list = self.trans_card(card)
        triple_list = []
        for c in set(card_list):
            c_cnt = card_list.count(c)
            if c_cnt >= 3:
                triple_list.append(c)
        res = []
        tips_list = []
        has_seq_set = set()
        for seq in seq_triple_list:
            if set(seq).issubset(set(triple_list)):
                has_seq_set |= set(seq)
                tips_card = []
                for c in seq:
                    rs = self.get_card_by_point(card, c, 3)
                    tips_card.extend(rs)
                tips_list.append(tips_card)
        has_seq_list = list(has_seq_set)
        for card_point in has_seq_list:
            rs = self.get_card_by_point(card, card_point)
            res.extend(rs)
        return res, tips_list
    
    def get_seq_triple_single_card(self, card, seq_s=0, num=2):
        '''取手牌中包含大于seq_s的飞机'''
        if len(card) < 4 * num:
            return [], []
        seq_triple_list = []
        end_c = 13 - num
        for start_c in range(seq_s+1, end_c+1):
            rs = range(start_c, start_c+num)
            seq_triple_list.append(rs)
        card_list = self.trans_card(card)
        triple_list = []
        for c in set(card_list):
            c_cnt = card_list.count(c)
            if c_cnt >= 3:
                triple_list.append(c)
        res = []
        tips_list = []
        has_seq_set = set()
        for seq in seq_triple_list:
            if set(seq).issubset(set(triple_list)):
                has_seq_set |= set(seq)
                with_card_list = []
                other_list = list(set(card_list) - set(seq))
                for c in other_list:
                    rs = self.get_card_by_point(card, c, 3)
                    with_card_list.extend(rs)
                tips_card = []
                with_card = []
                for c in seq:
                    rs = self.get_card_by_point(card, c, 3)
                    tips_card.extend(rs)
                    w = with_card_list.pop()
                    with_card.append(w)
                
                if '141' in with_card and '151' in with_card:
                    if with_card_list:
                        with_card.remove('141')
                        w = with_card_list.pop()
                        with_card.append(w)
                    else:
                        continue
                tips_card.extend(with_card)
                
                tips_list.append(tips_card)
        has_seq_list = list(has_seq_set)
        for card_point in has_seq_list:
            rs = self.get_card_by_point(card, card_point)
            res.extend(rs)
        if res:
            return card, tips_list
        return res, tips_list
    
    def get_seq_triple_pair_card(self, card, seq_s=0, num=2):
        '''取手牌中包含大于seq_s的飞机'''
        if len(card) < 5 * num:
            return [], []
        seq_triple_list = []
        end_c = 13 - num
        for start_c in range(seq_s+1, end_c+1):
            rs = range(start_c, start_c+num)
            seq_triple_list.append(rs)
        card_list = self.trans_card(card)
        triple_list = []
        pair_list = []
        for c in set(card_list):
            c_cnt = card_list.count(c)
            if c_cnt >= 3:
                triple_list.append(c)
            elif c_cnt == 2:
                pair_list.append(c)
        
        if len(triple_list) + len(pair_list) <= 2 * num:
            return [], []
        res = []
        tips_list = []
        has_seq_set = set()
        for seq in seq_triple_list:
            if set(seq).issubset(set(triple_list)):
                has_seq_set |= set(seq)
                with_card_list = []
                other_list = list((set(triple_list)|set(pair_list)) - set(seq))
                for c in other_list:
                    rs = self.get_card_by_point(card, c, 2)
                    with_card_list.extend(rs)
                tips_card = []
                with_card = []
                for c in seq:
                    rs = self.get_card_by_point(card, c, 3)
                    tips_card.extend(rs)
                    for i in range(2):
                        w = with_card_list.pop()
                        with_card.append(w)
                tips_card.extend(with_card)
                tips_list.append(tips_card)
        has_seq_list = list(has_seq_set)
        for card_point in has_seq_list:
            rs = self.get_card_by_point(card, card_point)
            res.extend(rs)
        return res, tips_list
    
    def check_validate(self, card, card_type):
        return self.get_card_type(card)[0] == card_type

    def get_valid_card(self, current_card, last_put_card, last_put_type='', last_put_point=''):
        valid_card = []
        if not last_put_type:
            last_put_type, last_put_point = self.get_card_type(last_put_card)
        if last_put_type == 'single':
            valid_card = self.get_single_card(current_card, int(last_put_point[0]))
        elif last_put_type == 'pair':
            valid_card = self.get_pair_card(current_card, int(last_put_point[0]))
        elif last_put_type == 'seq_pair':
            valid_card = self.get_seq_pair_card(current_card, int(last_put_point[0]), int(last_put_point[1])-int(last_put_point[0])+1)
        elif last_put_type == 'seq':
            valid_card = self.get_seq_card(current_card, int(last_put_point[0]), len(last_put_card))
        elif last_put_type == 'triple_one':
            valid_card = self.get_triple_one(current_card, int(last_put_point[0]))
        elif last_put_type == 'triple_two':
            valid_card = self.get_triple_two(current_card, int(last_put_point[0]))
        elif last_put_type == 'triple':
            valid_card = self.get_triple_card(current_card, int(last_put_point[0]))
        elif last_put_type == 'seq_triple':
            valid_card = self.get_seq_triple_card(current_card, int(last_put_point[0]), int(last_put_point[1])-int(last_put_point[0])+1)
        elif last_put_type == 'seq_triple_single':
            valid_card = self.get_seq_triple_single_card(current_card, int(last_put_point[0]), int(last_put_point[1])-int(last_put_point[0])+1)
        elif last_put_type == 'seq_triple_pair':
            valid_card = self.get_seq_triple_pair_card(current_card, int(last_put_point[0]), int(last_put_point[1])-int(last_put_point[0])+1)
        elif last_put_type == 'bomb_two':
            valid_card = self.get_bomb_two_card(current_card, int(last_put_point[0]))
        
        if last_put_type == 'rocket':
            valid_card = [], []
        elif last_put_type == 'bomb':
            valid_card = self.get_bomb_card(current_card, int(last_put_point[0]))
        else:
            bomb_card = self.get_bomb_card(current_card, 0)
            valid_list = bomb_card[0]
            tips_list = bomb_card[1]
            if valid_card:
                valid_card[0].extend(valid_list)
                valid_card[1].extend(tips_list)
            else:
                valid_card = bomb_card
        return valid_card
    
    def start(self):
        self.room['status'] = 'start'
        self.bottom_card.clear()
        game_round = int(self.room['game_round'])
        all_card = []
        for i in range(10, 140, 10):
            for j in range(1, 5):
                all_card.append(i+j)
        #加上小王和大王
        all_card.append(141)
        all_card.append(151)
        
        dealer = self.room['dealer']
        random.shuffle(all_card)
        random.shuffle(all_card)
        members = self.members
        all_card_num = len(all_card) - 3
        player_cnt = len(members)
        player_card = []
        every_player_num = all_card_num/player_cnt
        for uid in members:
            player_card.append({"uid":uid, "left_num":every_player_num, "bomb":0})
        
        user_card = {}
        for uid in members:
            card = []
            for i in range(every_player_num):
                card.append(all_card.pop())
            card.sort()
            card.reverse()
            user_card[uid] = card
            
        for uid in members:
            mid = self.incr_mid()
            player = Player(uid, self.bid, self.rid, True)
            card = user_card[uid]
            player.current_card.extend(card)
            card_list = [str(x) for x in card]
            nsq_pub({"b":self.bid, "u":str(uid), "t":"game", "d":{"act":"game_start", "status":"start", "left_card":0, "rid":self.rid, "mid":mid, "dealer":dealer, "card":card_list, "game_round":self.room['game_round'], "all_round":self.room['all_round'], "player_card":player_card}})
        self.current_card.clear()
        self.current_card.extend(all_card)
        self.room['last_put_user'] = ''
        self.room['last_put_card'] = ''
        self.room['last_put_type'] = ''
        self.room['last_put_point'] = ''
        
        logging.info(u"斗地主房间rid:%s,game_round:%s,发牌结束,通知%s出牌" % (self.rid, self.room['game_round'], dealer))
        
        match_id = self.room['mid']
        if match_id:
            idx = game_round % len(members)
            landlord = members[idx]
            self.notify_turn_rob(landlord)
            self.rob_landlord(landlord, {})
        else:
            self.notify_turn_rob(dealer)
            
    def notify_turn_rob(self, uid):
        #通知玩家叫地主
        self.room['stop_pop_user'] = uid
        self.room['stop_pop_act'] = 'turn_rob'
        for member in self.members:
            nsq_pub({"b":self.bid, "u":member, "t":"game", "d":{"act":"turn_rob", "uid":uid, "rid":self.rid}})
            
    def cancel_rob(self, uid, data={}):
        #不叫
        members = self.members
        for member in members:
            nsq_pub({"b":self.bid, "u":member, "t":"game", "d":{"act":"cancel_rob", "uid":uid, "rid":self.rid}})
            
        dealer = self.room['dealer']
        my_seat = members.index(uid)
        next_seat = (my_seat+1) % len(members)
        next_user = members[next_seat]
        if next_user == dealer:
            self.start()
            return
            
        self.notify_turn_rob(next_user)
    
    def rob_landlord(self, uid, data={}):
        #叫地主，发底牌
        self.room['dealer'] = uid
        self.bottom_card.clear()
        bottom_card = self.current_card.members
        if not bottom_card:
            return
        self.bottom_card.extend(bottom_card)
        self.current_card.clear()
        player = Player(uid, self.bid, self.rid)
        player.current_card.extend(bottom_card)
        card_list = player.current_card.members
        card_list.sort(key=lambda x:int(x), reverse=True)
        left_num = len(card_list)
        mid = self.incr_mid()
        for member in self.members:
            nsq_pub({"b":self.bid, "u":member, "t":"game", "d":{"act":"rob_landlord", "uid":uid, "mid":mid, "rid":self.rid, "bottom_card":bottom_card, "card":card_list, "left_num":left_num}})
        self.notify_keep_put(uid)
        
    def notify_keep_put(self, uid):
        self.room['stop_pop_user'] = uid
        self.room['stop_pop_act'] = 'put'
        self.room['last_get_user'] = uid
        self.room['last_put_user'] = ''
        self.room['last_put_card'] = ''
        self.room['last_put_type'] = ''
        self.room['last_put_point'] = ''
        members = self.members
        #player_cnt = len(members)
        max_single = 'n'
        #下家报单可以不出最大的牌
        match_id = self.room['mid']

        for member in members:
            if member == uid:
                tips_list = []
                player = Player(uid, self.bid, self.rid)
                all_card = player.current_card.members
                #current_card = sorted(all_card, key=lambda x:int(x))
                #for c in current_card:
                #    tips_list.append([c])
                card_type, card_point = self.get_card_type(all_card)
                if card_type and card_type not in ('bomb_one', 'bomb_two',):
                    tips_list.append(all_card)
            else:
                all_card = []
                tips_list = []
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"act":"turn_put", "put_type":"free", "max_single":max_single, "uid":uid, "valid_list":all_card, "rid":self.rid, "tips_list":tips_list, "last_put_card":[], "last_put_type":"", "last_put_point":[]}})
        
        if match_id:
            current_user = Hash("%s_%s" % (self.bid, uid))
            if current_user['online'] != 'y' or current_user['rid'] != self.rid:
                self.auto_put(uid)
            
    def notify_next_user(self, pre_user):
        members = self.members
        pre_user_seat = members.index(pre_user)
        next_user_seat = (pre_user_seat + 1) % len(members)
        next_user = members[next_user_seat]
        self.room['stop_pop_user'] = next_user
        self.room['stop_pop_act'] = 'put'
        last_put_user = self.room['last_put_user']
        if not last_put_user or next_user == last_put_user:
            #首次出牌或者过一圈没人能打起
            self.notify_keep_put(next_user)
            return
        else:
            max_single = 'n'
            last_put_card = self.room['last_put_card'].split(",")
            last_put_type = self.room['last_put_type']
            last_put_point = self.room['last_put_point'].split(",")
            if last_put_point:
                last_put_point = [int(x) for x in last_put_point]
            #判断下家能否打牌,没有打牌则自动发送要不起,否则发送出牌通知
            #last_put_type, last_put_point = self.get_card_type(last_put_card)
            p = Player(next_user, self.bid, self.rid)
            current_card = p.current_card.members
            logging.info(u"判断下家是否有牌:%s, last_put_card:%s, type:%s, point:%s" % (next_user, str(last_put_card), last_put_type, str(last_put_point)))
            valid_card = self.get_valid_card(current_card, last_put_card, last_put_type, last_put_point)
            match_id = self.room['mid']
                    
            for member in members:
                if member == next_user:
                    valid_list, tips_list = valid_card
                    logging.info(u"下家%s可出的牌有:valid_list:%s, tips_list:%s" % (member, str(valid_list), str(tips_list)))
                else: 
                    #logging.info(u"=============member:%s,next_user:%s" % (member, next_user))
                    valid_list, tips_list = [], []
                nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"act":"turn_put", "put_type":"follow", "max_single":max_single, "uid":next_user, "rid":self.rid, "valid_list":valid_list, "tips_list":tips_list, "last_put_card":last_put_card, "last_put_type":last_put_type, "last_put_point":last_put_point}})
            
            if match_id:
                current_user = Hash("%s_%s" % (self.bid, next_user))
                if current_user['online'] != 'y' or current_user['rid'] != self.rid:
                    self.auto_put(next_user)
    
    def pass_card(self, uid, data={}):
        stop_pop_user = self.room['stop_pop_user']
        if uid != stop_pop_user:
            logging.error(u"pass,该%s打牌,不该%s" % (stop_pop_user, uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        mid = self.incr_mid()
        members = self.members
        for member in members:
            nsq_pub({"b":self.bid, "u":member, "t":"game", "d":{"act":"pass", "mid":mid, "uid":uid, "rid":self.rid}})
        self.notify_next_user(uid)
        
    def put_card(self, uid, data):
        uid = str(uid)
        stop_pop_user = self.room['stop_pop_user']
        stop_pop_act = self.room['stop_pop_act']
        if not (uid == stop_pop_user and stop_pop_act == 'put'):
            logging.error(u"该%s操作%s,不该%s出牌" % (stop_pop_user, stop_pop_act, uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        card = data['card']
        if not isinstance(card, list):
            card = card.split(",")
        put_card_type = self.get_card_type(card)
        logging.info(u"斗地主%s检查用户%s牌型%s,%s" % (self.rid, uid, put_card_type[0], put_card_type[1]))
        card_type = put_card_type[0]
        if not card_type:
            #牌型不符合
            logging.error(u"斗地主%s玩家%s出牌不符合规范,%s" % (self.rid, uid, ",".join(card)))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return 
        
        current_player = Player(uid, self.bid, self.rid)
        user_current_card = current_player.current_card.members
        current_player.score['put_num'] = int(current_player.score['put_num']) + 1
        for c in card:
            if c not in user_current_card:
                logging.error(u"斗地主%s出牌异常,用户%s没有该手牌,%s" % (self.rid, uid, c))
                get_last_data('', self.bid, uid, {"rid":self.rid})
                return
        #if card_type in ('triple', 'triple_one', 'bomb_two', 'bomb_one'):
        #    if len(user_current_card) != len(card):
        #        logging.error(u"出牌异常,用户%s只有最后一手才能出三带一和不带%s" % (uid, str(card)))
        #        get_last_data('', self.bid, uid, {"rid":self.rid})
        #        return
        #elif card_type == 'seq_triple':
        #    seq_s, seq_e = put_card_type[1]
        #    if len(user_current_card) != len(card) and len(card) != (seq_e - seq_s + 1)*5:
        #        logging.error(u"出牌异常,用户%s只有最后一手才能飞机少带%s" % (uid, str(card)))
        #        get_last_data('', self.bid, uid, {"rid":self.rid})
        #        return
        #last_put_type = self.room['last_put_type']
        #last_put_user = self.room['last_put_user']
        last_put_point = self.room['last_put_point']
        logging.info(u"last_put_point===:%s" % str(last_put_point))
        last_put_card = self.room['last_put_card']
        members = self.members
        if last_put_card:
            #跟上家的牌
            put_type = 'follow'
            card1 = last_put_card.split(",")
            if not self.compare_card(card1, card):
                logging.error(u"出牌异常,用户%s出牌牌不能大过上家,%s" % (uid, ",".join(card)))
                get_last_data('', self.bid, uid, {"rid":self.rid})
                return
        else:
            #自由出牌
            put_type = 'free'
        
        for c in card:
            current_player.current_card.remove(c, 1)
            current_player.out_card.append(c)
        
        self.room['last_put_card'] = ",".join(card)
        self.room['last_put_type'] = card_type
        self.room['last_put_point'] = ",".join([str(x) for x in put_card_type[1]])
        self.room['last_put_user'] = uid
        
        user_left_card = current_player.current_card.members
        left_num = len(user_left_card)
        mid = self.incr_mid()
        for member in members:
            if card_type in('bomb', 'rocket'):
                if member == str(uid):
                    self.room['bomb'] = int(self.room['bomb']) + 1 
                    current_player.score['bomb'] =  int(current_player.score['bomb']) + 1
                    
            if member == str(uid):
                left_card = user_left_card
            else:
                left_card = []
                
            nsq_pub({"b":self.bid, "u":member, "t":"game", "d":{"act":"put_card", "mid":mid, "put_type":put_type, "left_card":left_card, "left_num":left_num, "uid":uid, "rid":self.rid, "card":card, "card_type":card_type}})
        
        if user_left_card:
            #card_warning = self.room['card_warning']
            #if not card_warning:
            #    card_warning = 1
            #else:
            #    card_warning = int(card_warning)
            card_warning = 2
            if left_num <= card_warning:
                for member in members:
                    nsq_pub({"b":self.bid, "u":member, "t":"game", "d":{"act":"card_warning", "left_num":left_num, "uid":uid, "rid":self.rid}})
            self.notify_next_user(uid)
        else:
            self.game_over(uid)
    
    def auto_put(self, uid):
        uid = str(uid)
        stop_pop_user = self.room['stop_pop_user']
        if uid != stop_pop_user:
            logging.error(u"该%s出牌,不该%s" % (stop_pop_user, uid))
            return
        last_put_user = self.room['last_put_user']
        p = Player(uid, self.bid, self.rid)
        if not last_put_user or uid == last_put_user:
            #首次出牌或者过一圈没人能打起
            current_card = sorted(p.current_card.members, key=lambda x:int(x))
            card = current_card[0]
            data = {"card":[card]}
            self.put_card(uid, data)
            return
        else:
            last_put_card = self.room['last_put_card'].split(",")
            last_put_type = self.room['last_put_type']
            last_put_point = self.room['last_put_point'].split(",")
            current_card = p.current_card.members
            valid_list, tips_list = self.get_valid_card(current_card, last_put_card, last_put_type, last_put_point)
            if tips_list:
                card = tips_list[0]
                data = {"card":card}
                self.put_card(uid, data)
            else:
                self.pass_card(uid)
                
    def game_over(self, winner='', from_dissmiss=False, duty_uid=''):
        if from_dissmiss:
            from_dissmiss = "y"
        else:
            from_dissmiss = "n"
        dealer = self.room['dealer']
        db = dao.Game_DB()
        player_card = []
        match_id = self.room['mid']
        game_type = self.room['game_type']
        game_round = self.room['game_round']
        if not game_round:
            game_round = 1
        else:
            game_round = int(game_round)
        
        all_round = self.room['all_round']
        if not all_round:
            all_round = 1
        else:
            all_round = int(all_round)
            
        if match_id:
            lose_score = get_match_base_score(self.bid, match_id, all_round, game_round, self.rid)
        else:
            lose_score = 1
        win_score = 0
        win_type = ""
        dealer_win = False
        if winner:
            if winner == dealer:
                dealer_win = True
            else:
                dealer_win = False
            
            win_type = self.get_win_type(dealer, dealer_win)
            if win_type:
                lose_score *= 2 
            bomb = int(self.room['bomb'])
            if bomb:
                max_bomb = self.room['max_bomb']
                if not max_bomb:
                    max_bomb = 5
                else:
                    max_bomb = int(max_bomb)
                if bomb > max_bomb:
                    bomb = max_bomb
                lose_score *= 2**bomb
            
            if dealer_win:
                #地主赢
                for member in self.members:
                    p = Player(member, self.bid, self.rid)
                    if member != dealer:
                        p.score['score'] = int(p.score['score']) - lose_score
                        #p.score['win_score'] = "-%s" % lose_score
                    else:
                        p.score['score'] = int(p.score['score']) + lose_score*2
                        #p.score['win_score'] = str(lose_score*2)
            else:
                for member in self.members:
                    p = Player(member, self.bid, self.rid)
                    if member != dealer:
                        p.score['score'] = int(p.score['score']) + lose_score
                    else:
                        p.score['score'] = int(p.score['score']) - lose_score*2
        
        for uid in self.members:
            if not uid:
                continue
            p = Player(uid, self.bid, self.rid)
            # 重置玩家状态,和计算分数
            bomb = p.score['bomb']
            p_data = {"uid":uid, "score":p.score['score'], "current_card":p.current_card.members, "bomb":bomb}
            if not winner:
                score = 0
                p_data['score'] = "0"
            else:
                score = int(p.score['score'])
            if dealer == uid:
                is_dealer = "y"
            else:
                is_dealer = "n"
            if (dealer_win and uid == dealer) or (not dealer_win and uid != dealer):
                is_win = 1
            else:
                is_win = 0
            p_data['is_dealer'] = is_dealer
            db.update_player(self.rid, uid, score, 0)
            db.commit()
            player_info = db.get_player(self.rid, uid)
            p_data['user_score'] = player_info['score']
            player_card.append(p_data)
            db.add_room_log(0, 0, self.rid, game_round, uid, score, 0, bomb, is_dealer, is_win, 0, win_type)
            db.commit()
        rules = {}
        #room_info = db.get_room(self.rid, self.bid)
        #gid = room_info.get("gid")
        gid = self.room['gid']
        if gid:
            rows = db.game_rule(gid)
        else:
            rows = db.room_rule(self.rid)
            gid = ""
        for row in rows:
            k = row['param']
            v = row['value']
            rules[k] = v
        
        mid = self.incr_mid()
        for uid in self.members:
            try:
                if (dealer_win and uid == dealer) or (not dealer_win and uid != dealer):
                    win_round = 1
                    is_win = 'y'
                else:
                    win_round = 0
                    is_win = 'n'
                pub_data = {"b":self.bid, "u":str(uid), "t":"game", "d":{"is_win":is_win, "match_id":"", "gid":gid, "rules":rules, "win_type":win_type, "from_dissmiss":from_dissmiss, "dealer":dealer, "game_round":game_round, "player_card":player_card, "mid":mid, "act":"game_over", "winner":winner, "rid":self.rid}}
                nsq_pub(pub_data)
                db.save_game_over(self.rid, game_round, "game_over", uid, json_encode(pub_data))
                db.commit()
                if db.has_user_stat(self.bid, uid, game_type):
                    db.update_user_stat(self.bid, uid, game_type, win_round)
                else:
                    db.add_user_stat(self.bid, uid, game_type, win_round, 0)
            except:
                logging.error(u"统计用户生涯错误:%s" % uid, exc_info=True)
        logging.info(u"斗地主房间%s第%s局结束" % (self.rid, game_round))
        if winner:
            self.room['dealer'] = winner
        self.room['status'] = 'over'
        self.room['stop_pop_user'] = ''
        self.room['last_put_user'] = ''
        self.room['last_get_card'] = ''
        self.room['last_put_type'] = ''
        self.room['last_get_point'] = ''
        db.game_over(self.rid, game_round)
        db.commit()
        self.room['game_round'] = game_round + 1
        
        if match_id:
            nsq_pub({"b":self.bid, "u":"", "t":"game", "d":{"all_round":all_round, "match_id":match_id, "rules":rules, "win_type":"", "from_dissmiss":from_dissmiss,"dealer":self.room['dealer'], "game_round":self.room['game_round'], "player_card":player_card, "mid":mid, "act":"game_over", "winner":winner, "card":"", "rid":self.rid, "all_horse_card":[], "horse_card":[], "horse_num":0}}, "match_club")
        if all_round <= game_round:
            self.dismiss(act='room_over')
        else:
            if match_id:
                exp_time = (datetime.datetime.now() + datetime.timedelta(seconds=5)).strftime("%Y-%m-%d %H:%M:%S")
                db.add_cron(self.bid, "auto_ready", self.rid, 0, exp_time)
                db.commit()
        
        
    def dismiss(self, act='room_over'):
        db = dao.Game_DB()
        player_data = {}
        player_stat = []
        if not self.room['status']:
            logging.info(u"房间结束,未开始:%s" % self.rid)
            deduct_flag = False
            winner = ""
            for uid in self.members:
                player_stat.append({"uid":uid,"score":0,"win_num":0, "max_score":0, "lose_num":0, "bomb":0})
        else:
            p_stat = db.player_stat(self.rid)
            for ps in p_stat:
                tmp = {}
                tmp['uid'] = ps['uid']
                tmp['score'] = int(ps['score'])
                tmp['win_num'] = int(ps['win_num'])
                tmp['max_score'] = int(ps['max_score'])
                tmp['lose_num'] = int(ps['lose_num'])
                tmp['bomb'] = int(ps['dark_bar'])
                player_stat.append(tmp)
                player_data[str(ps['uid'])] = tmp
            deduct_flag = True
            if p_stat:
                winner = p_stat[-1]['uid']
            else:
                winner = ""
            # 排序最后一家为大赢家
            #player_stat = p_stat
         
        room_info = db.get_room(self.rid, self.bid)
        admin = room_info['admin']
        match_id = room_info['mid']
        gid = room_info['gid']
        if not gid:
            gid = 0
        else:
            for ps in player_stat:
                if ps['uid'] == winner:
                    is_winner = 'y'
                else:
                    is_winner = 'n'
                db.add_room_stat(match_id, gid, self.rid, ps['uid'], ps['score'], is_winner)
                db.commit()
            
        if not match_id:
            #比赛的房间不发送room_over
            for member in self.members:
                pub_data = {"b":self.bid, "u":member, "t":"game", "d":{"act":"room_over", "rid":self.rid, "player_stat":player_stat, "winner":winner, "admin":admin}}
                nsq_pub(pub_data)
                db.save_game_over(self.rid, 0, "room_over", member, json_encode(pub_data))
                db.commit()
        else:
            #比赛房间不扣房卡
            deduct_flag = False
        db.dismiss_room(self.rid)
        db.commit()
        game_type = self.room['game_type']
        if match_id or gid:
            nsq_pub({"b":self.bid, "u":"", "t":"game", "d":{"game_type":game_type, "match_id":match_id, "gid":gid, "act":"room_over", "rid":self.rid, "player_stat":player_stat, "winner":winner, "admin":admin}}, "match_club")
            
        #if deduct_flag:
        #    card = room_info['card']
        #    db.deduct_card(self.bid, admin, card)
        #    nsq_pub({"act":"deduct_card", "bid":self.bid, "uid":admin, "card":card, "rid":self.rid}, "total")
        #    logging.info(u"斗地主房间%s解散成功,扣除房卡, bid:%s,uid:%s,card:%s" % (self.rid, self.bid, admin, card))
        #else:
        #    logging.info(u"斗地主房间%s解散成功,游戏无需扣房卡" % self.rid)
        for member in self.members:
            player = Player(member, self.bid, self.rid)
            player.clear()
        redisco.connection.delete("r:%s:current_card" % self.rid)
        redisco.connection.delete("r:%s:out_card" % self.rid)
        redisco.connection.delete("r:%s" % self.rid)
        redisco.connection.delete("r:%s:mid" % self.rid)
        redisco.connection.delete("r:%s:p" % self.rid)
        
        